package com.mimiwang.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mimiwang.common.utils.*;
import com.mimiwang.user.entity.vo.LoginByMobileEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.mimiwang.user.dao.UserInfoDao;
import com.mimiwang.user.entity.UserInfoEntity;
import com.mimiwang.user.service.UserInfoService;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;

import javax.servlet.http.HttpServletRequest;


@Service("userInfoService")
@Slf4j
public class UserInfoServiceImpl extends ServiceImpl<UserInfoDao, UserInfoEntity> implements UserInfoService {

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserInfoEntity> page = this.page(
                new Query<UserInfoEntity>().getPage(params),
                new QueryWrapper<UserInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void sendSecurityCode(String mobile) {

        String code = AliyunUtil.sendMsm(mobile, "咪咪汪");
        // 将发送的验证码存入redis,并设置过期时间为3分钟。
        redisTemplate.opsForValue().set(mobile, code, 3, TimeUnit.MINUTES);


    }

    @Override
    public boolean register(String code, UserInfoEntity userInfoEntity) {
        String expectCode = null;
        try {
            expectCode = (String) redisTemplate.opsForValue().get(userInfoEntity.getMobile());
        } catch (Exception e) {
            log.info("redis中无该手机号");
            e.printStackTrace();
        }
        if (code.equals(expectCode)) {
            baseMapper.insert(userInfoEntity);
            return true;
        }
        return false;
    }


    /**
     * 检验用户名是否存在
     *
     * @param userName
     * @return 不存在返回true，存在返回false
     */
    @Override
    public boolean isExistedUserName(String userName) {
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        UserInfoEntity userInfoEntity = baseMapper.selectOne(wrapper);


        if (userInfoEntity == null) {
            return true;
        }
        return false;
    }


    /**
     * @param mobile
     * @return 如果手机号还未被注册，返回true，否则返回false。
     */
    @Override
    public boolean isExistedMobile(String mobile) {

        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile", mobile);
        UserInfoEntity userInfoEntity = baseMapper.selectOne(wrapper);
        if (userInfoEntity == null) {
            return true;
        }
        return false;
    }


    /**
     * @param userName
     * @param password
     * @return 0 用户名不存在 1密码错误 2 验证成功
     */

    @Override
    public int verifyUserInfo(String userName, String password, HttpServletRequest request) {
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        UserInfoEntity userInfoEntity = baseMapper.selectOne(wrapper);
        if (userInfoEntity == null) {
            return 0;
        }
        boolean correct = userInfoEntity.getPassword().equals(password);
        String ipAddress = NetworkUtils.getIpAddress(request);
        Integer num = null;
        if (!correct) {


            num = (Integer) redisTemplate.opsForValue().get(ipAddress);
            if (num == null) {

                redisTemplate.opsForValue().set(ipAddress, 1, 10, TimeUnit.MINUTES);
            } else {

                redisTemplate.opsForValue().set(ipAddress, ++num, 10, TimeUnit.MINUTES);
            }

            return 1;
        }
        return 2;
    }

    /**
     * @param request
     * @return 如果密码错误次数大于五次，那么就限制登录10分钟
     */

    @Override
    public boolean checkLoginIncorrect(HttpServletRequest request) {
        String ipAddress = NetworkUtils.getIpAddress(request);
        Integer incorrectNum = (Integer) redisTemplate.opsForValue().get(ipAddress);
        if (incorrectNum != null && incorrectNum > 5) {
            return true;
        }
        return false;
    }

    /**
     * @param mobile
     * @param verifyCode
     * @return 如果手机号和验证码验证通过返回true，否则返回false;
     */
    @Override
    public boolean verifyMobileVerify(String mobile, String verifyCode) {


        String expectedCode = (String) redisTemplate.opsForValue().get(mobile);

        log.info(mobile);
        if (verifyCode.equals(expectedCode)) {
            return true;
        }
        return false;
    }

    @Override
    public UserInfoEntity selectByMobile(String mobile) {
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile", mobile);
        UserInfoEntity userInfoEntity = baseMapper.selectOne(wrapper);
        if (userInfoEntity != null) {
            userInfoEntity.setPassword(null);
        }
        return userInfoEntity;
    }

    @Override
    public String distributeToken(Long userId, String userName) {


        return JwtUtil.getToken(new HashMap<String, String>() {{
            put("userName", userName);
            put("userId", String.valueOf(userId));
        }});
    }

    @Override
    public UserInfoEntity getUserInfoByUserId(Long userId) {
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);

        UserInfoEntity userInfoEntity = baseMapper.selectOne(wrapper);
        if (userInfoEntity != null) {
            userInfoEntity.setPassword(null);
        }
        return userInfoEntity;
    }

    @Override
    public Long selectByUserName(String userName) {
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        UserInfoEntity userInfoEntity = baseMapper.selectOne(wrapper);

        // 如果数据库中不存在该userName，则返回-1L
        if (userInfoEntity == null) {
            return -1L;
        }
        userInfoEntity.setPassword(null);
        Long userId = userInfoEntity.getUserId();
        return userId;

    }
}